<!-- 表格搜索栏 -->
<template>
  <section
    class="search-bar art-custom-card"
    :class="{ 'is-expanded': isExpanded }"
  >
    <ElForm :model="filter" :label-position="labelPosition">
      <ElRow class="search-form-row" :gutter="gutter">
        <ElCol
          v-for="item in visibleFormItems"
          :key="item.prop"
          :xs="24"
          :sm="12"
          :md="item.elColSpan || elColSpan"
          :lg="item.elColSpan || elColSpan"
          :xl="item.elColSpan || elColSpan"
        >
          <ElFormItem
            :label="item.label"
            :prop="item.prop"
            :label-width="labelWidth"
          >
            <component
              :is="getComponent(item.type)"
              v-model:value="filter[item.prop]"
              :item="item"
            />
          </ElFormItem>
        </ElCol>
        <ElCol
          :xs="24"
          :sm="24"
          :md="elColSpan"
          :lg="elColSpan"
          :xl="elColSpan"
          class="action-column"
        >
          <div class="action-buttons-wrapper" :style="actionButtonsStyle">
            <div class="form-buttons">
              <ElButton class="reset-button" @click="handleReset" v-ripple>
                {{ t("table.searchBar.reset") }}
              </ElButton>
              <ElButton
                type="primary"
                class="search-button"
                @click="handleSearch"
                v-ripple
              >
                {{ t("table.searchBar.search") }}
              </ElButton>
            </div>
            <div
              v-if="shouldShowExpandToggle"
              class="filter-toggle"
              @click="toggleExpand"
            >
              <span>{{ expandToggleText }}</span>
              <div class="icon-wrapper">
                <ElIcon>
                  <ArrowUpBold v-if="isExpanded" />
                  <ArrowDownBold v-else />
                </ElIcon>
              </div>
            </div>
          </div>
        </ElCol>
      </ElRow>
    </ElForm>
  </section>
</template>

<script setup lang="ts">
import { ArrowUpBold, ArrowDownBold } from "@element-plus/icons-vue";
import { useWindowSize } from "@vueuse/core";
import { useI18n } from "vue-i18n";
import { markRaw } from "vue";
import ArtSearchInput from "./widget/art-search-input/index.vue";
import ArtSearchSelect from "./widget/art-search-select/index.vue";
import ArtSearchRadio from "./widget/art-search-radio/index.vue";
import ArtSearchDate from "./widget/art-search-date/index.vue";
import type { SearchComponentType, SearchFormItem } from "@/types";
import type { Component } from "vue";

defineOptions({ name: "ArtSearchBar" });

const { width } = useWindowSize();
const { t } = useI18n();
const isMobile = computed(() => width.value < 500);

type FilterValue = string | number | undefined | null | unknown[];
type FilterData = Record<string, FilterValue>;

interface SearchBarProps {
  /** 查询参数 */
  filter: FilterData;
  /** 表单数据 */
  items: SearchFormItem[];
  /** 每列的宽度（基于 24 格布局） */
  elColSpan?: number;
  /** 表单控件间隙 */
  gutter?: number;
  /** 展开/收起 */
  isExpand?: boolean;
  /** 表单域标签的位置 */
  labelPosition?: "left" | "right";
  /** 文字宽度 */
  labelWidth?: string;
  /** 是否需要展示，收起 */
  showExpand?: boolean;
  /** 按钮靠左对齐限制（表单项小于等于该值时） */
  buttonLeftLimit?: number;
}

const props = withDefaults(defineProps<SearchBarProps>(), {
  elColSpan: 6,
  gutter: 12,
  isExpand: false,
  labelPosition: "right",
  labelWidth: "70px",
  showExpand: true,
  buttonLeftLimit: 2,
});

interface SearchBarEmits {
  "update:filter": [filter: FilterData];
  reset: [];
  search: [];
}

const emit = defineEmits<SearchBarEmits>();

/**
 * 是否展开状态
 */
const isExpanded = ref(false);

/**
 * 组件映射表（使用 markRaw 优化性能）
 */
const componentsMap = markRaw({
  input: ArtSearchInput,
  select: ArtSearchSelect,
  radio: ArtSearchRadio,
  checkbox: ArtSearchSelect, // 复用 select 组件
  datetime: ArtSearchDate,
  date: ArtSearchDate,
  daterange: ArtSearchDate,
  datetimerange: ArtSearchDate,
  month: ArtSearchDate,
  monthrange: ArtSearchDate,
  year: ArtSearchDate,
  yearrange: ArtSearchDate,
  week: ArtSearchDate,
  time: ArtSearchDate,
  timerange: ArtSearchDate,
} as const satisfies Record<SearchComponentType, Component>);

/**
 * 可见的表单项
 */
const visibleFormItems = computed(() => {
  const shouldShowLess = !props.isExpand && !isExpanded.value;
  if (shouldShowLess) {
    const maxItemsPerRow = Math.floor(24 / props.elColSpan) - 1;
    return props.items.slice(0, maxItemsPerRow);
  }
  return props.items;
});

/**
 * 查询参数的双向绑定
 */
const filter = computed({
  get: () => props.filter,
  set: (value) => emit("update:filter", value),
});

/**
 * 是否应该显示展开/收起按钮
 */
const shouldShowExpandToggle = computed(() => {
  return (
    !props.isExpand &&
    props.showExpand &&
    props.items.length > Math.floor(24 / props.elColSpan) - 1
  );
});

/**
 * 展开/收起按钮文本
 */
const expandToggleText = computed(() => {
  return isExpanded.value
    ? t("table.searchBar.collapse")
    : t("table.searchBar.expand");
});

/**
 * 操作按钮样式
 */
const actionButtonsStyle = computed(() => ({
  "justify-content": isMobile.value
    ? "flex-end"
    : props.items.length <= props.buttonLeftLimit
      ? "flex-start"
      : "flex-end",
}));

/**
 * 获取对应的组件
 */
function getComponent(type: SearchComponentType): Component {
  return componentsMap[type];
}

/**
 * 切换展开/收起状态
 */
function toggleExpand() {
  isExpanded.value = !isExpanded.value;
}

/**
 * 处理重置事件
 */
function handleReset() {
  emit("reset");
}

/**
 * 处理搜索事件
 */
function handleSearch() {
  emit("search");
}

// 解构 props 以便在模板中直接使用
const { elColSpan, gutter, labelPosition, labelWidth } = toRefs(props);
</script>

<style lang="scss" scoped>
.search-bar {
  padding: 15px 20px 0;
  background-color: var(--art-main-bg-color);
  border-radius: calc(var(--custom-radius) / 2 + 2px);

  :deep(.el-form-item--default) {
    margin-bottom: 15px;
  }

  &.is-expanded {
    :deep(.el-form-item--default) {
      margin-bottom: 18px;
    }
  }

  :deep(.el-form-item__label) {
    display: flex;
    align-items: center;
    line-height: 20px;
  }

  .search-form-row {
    display: flex;
    flex-wrap: wrap;
  }

  .action-column {
    flex: 1;
    max-width: 100%;

    .action-buttons-wrapper {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      justify-content: flex-end;
      margin-bottom: 12px;
    }

    .form-buttons {
      display: flex;
      gap: 8px;
    }

    .filter-toggle {
      display: flex;
      align-items: center;
      margin-left: 10px;
      line-height: 32px;
      color: var(--main-color);
      cursor: pointer;
      transition: color 0.2s ease;

      &:hover {
        color: var(--el-color-primary);
      }

      span {
        font-size: 14px;
        user-select: none;
      }

      .icon-wrapper {
        display: flex;
        align-items: center;
        margin-left: 4px;
        font-size: 14px;
        transition: transform 0.2s ease;
      }
    }
  }
}

// 响应式优化
@media (width <= 768px) {
  .search-bar {
    padding: 16px 16px 0;

    .action-column {
      .action-buttons-wrapper {
        flex-direction: column;
        gap: 8px;
        align-items: stretch;

        .form-buttons {
          justify-content: center;
        }

        .filter-toggle {
          justify-content: center;
          margin-left: 0;
        }
      }
    }
  }
}
</style>
